'use strict';
/**
 * author：小小游 --- allen
 * date：2018.02.04
 * lastUpdateDate：2018.02.04
 * description：Iterator遍历器与for-of循环的配合使用
 */
// 来看看怎么玩耍Iterator遍历器与for-of循环
/**
 * 数组有一个Symbol.iterator的属性，当我们调用它arr[Symbol.iterator]()，
 * 它会返回一个Iterator的指针对象，如下所示：
 * 那么它调用next方法会返回两个值，格式为：{ value: 'a', done: false }
 * value表示当前正在循环遍历的值，done为false表示循环还没结束，就得继续调用
 * next()方法，直到{ value: undefined, done: true }表示值已经遍历完毕
 */
class UserGroup {
    constructor (users) {
        /**
         * users：{ name1 : qq1, name2 : qq2 }
         * users：{ 'allen' : '214913005', 'xiaoyou' : '2470939843' }
         */
        this.users = users;
    }

    // 方法的名字就是Symbol.iterator
    [Symbol.iterator] () {

        // UserGroup { users：{ 'allen' : '214913005', 'xiaoyou' : '2470939843' } }
        // console.log(this);
        var _this = this;

        /**
         * 注意：这些变量的定义必须在Symbol.iterator属性方法里来定义，
         * 我们要把每一次Iterator调用之后返回的Iterator的指针对象，保证
         * 每次调用都是一个全新的Iterator，所以说每次调用初始化的这些变量
         * 都要重新初始化
         *
         */
        // 给个初始值
        let i = 0;
        // 得到所有的names，类似上面的key(allen, xiaoyou)
        const names = Object.keys(this.users);
        const length = names.length;
        // console.log(names);

        // 返回的是iterator的一个指针对象
        return {
            next: function () {
                let name = names[i++];
                // next: [Function next] 这里的this指向有问题的
                // console.log(this);
                // let qq = this.users[name];
                let qq = _this.users[name];
                return {
                    value : { name, qq },
                    done : i > length
                };
            }
        }
    }
}

let userGroup = new UserGroup({ 'allen' : '214913005', 'xiaoyou' : '2470939843' });

/**
 * for-of循环的优势就是既简便，可以中途跳出和停止循环又弥补
 * forEach那个方法的弊端，无法在中途跳出和停止循环
 */
let i = 0;
for ( let user of userGroup ) {
    if ( i === 0 ) {
        i++;
        continue;
    }
    // 直接打印出第一条数据来，然后跳出整个循环
    console.log(user);
    // break;
}

/**
 * class也有一个Symbol.iterator的属性，当我们调用它userGroup[Symbol.iterator]()，
 * 它会返回一个Iterator的指针对象，如下所示：
 * 那么它调用next方法会返回两个值，格式如下：
 * { value: { name: 'allen', qq: '214913005' }, done: false }
 * value表示当前正在循环遍历的值，done为false表示循环还没结束，就得继续调用
 * next()方法，直到{ value: { name: undefined, qq: undefined }, done: true }
 * 表示值已经遍历完毕
 */
// let iterator = userGroup[Symbol.iterator]();
// console.log(iterator.next());
// console.log(iterator.next());
// console.log(iterator.next());
